package com.sxhuayuan.parking.controller.admin;

import com.sxhuayuan.parking.compenent.Pageable;
import com.sxhuayuan.parking.compenent.web.RespMessage;
import com.sxhuayuan.parking.controller.BaseController;
import com.sxhuayuan.parking.entity.Admin;
import com.sxhuayuan.parking.entity.Agent;
import com.sxhuayuan.parking.entity.MonthlyProfit;
import com.sxhuayuan.parking.entity.ProfitStatistics;
import com.sxhuayuan.parking.service.AdminService;
import com.sxhuayuan.parking.service.AgentService;
import com.sxhuayuan.parking.service.MonthlyProfitService;
import com.sxhuayuan.parking.service.ProfitStatisticsService;
import com.sxhuayuan.parking.task.MonthlyProfitTask;
import com.sxhuayuan.parking.utils.ExcelUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.task.TaskExecutor;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.persistence.EntityNotFoundException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 代理分润月结算
 * 
 * @author 何龙
 * @create 2019-05-23 9:29
 */
@RestController(value = "adminMonthlyProfitController")
@RequestMapping("/admin/monthlyprofit")
public class MonthlyProfitController extends BaseController {
	Logger log = LoggerFactory.getLogger(getClass());

	@Resource(name = "monthlyProfitServiceImpl")
	MonthlyProfitService service;

	@Resource(name = "profitStatisticsServiceImpl")
	ProfitStatisticsService profitStatisticsService;

	@Resource(name = "taskExecutor")
	TaskExecutor taskExecutor;

	@Resource(name = "adminServiceImpl")
	AdminService adminService;

	@Resource(name = "agentServiceImpl")
	AgentService agentService;

	@PostMapping("/list")
	public RespMessage list(@RequestBody Pageable pageable) {
		return successResp(service.findByPageable(pageable, null));
	}

	/**
	 * 根据查询条件统计分润
	 *
	 * @param pageable
	 *            分页查询条件
	 * @return 总分润 微信分润 支付宝分润
	 */
	@PostMapping("/sum/money")
	public RespMessage sumMoney(@RequestBody Pageable pageable) {
		BigDecimal[] bigDecimals = service.sumByPage(pageable, null);
		return successResp(bigDecimals);
	}

	/** 修改分润统计状态 */
	@PostMapping("/update/state")
	public RespMessage updateState(@RequestParam Long id, @RequestParam MonthlyProfit.State state) {
		Admin current = adminService.getCurrent();
		if (current == null) {
			return RespMessage.error("登录失效，请重新登录");
		}
		if (state != MonthlyProfit.State.waitRemittance && state != MonthlyProfit.State.remittance) {
			return RespMessage.error("非法状态修改");
		}
		MonthlyProfit one = service.findOne(id);
		if (one == null) {
			return RespMessage.error("分润记录不存在");
		} else if (one.getAgent().getParent() != null) {
			return RespMessage.error("无权操作");
		}
		one.setState(state);
		service.update(one);
		log.debug("admin：{}=>代理[{}],{}月分润状态修改为{}", current.getName(), one.getAgent().getName(), one.getStatistisMonth().getMonthValue(), one.getState());
		return RespMessage.success();

	}

	/**
	 * 初始化代理分润月结算
	 * 
	 * @param n
	 *            初始化前n月的结算
	 */
	@GetMapping("/init")
	public RespMessage initProfitStatistics(int n) {
		if (n <= 0 || n > 12) {
			return RespMessage.error("n必须为1-12的整数");
		}
		for (int i = 1; i <= n; i++) {
			LocalDate date = LocalDate.now().minusMonths(i);
			log.debug("添加分润月结算统计任务: {}", date.format(DateTimeFormatter.ofPattern("yyyy-MM")));
			taskExecutor.execute(new MonthlyProfitTask(date));
		}
		return RespMessage.success("已添加任务数:" + n);
	}

	/** 下载报表 */
	@GetMapping("/download/excel/{id}")
	public RespMessage downloadExcel(@PathVariable("id") Long id, @RequestParam int year, @RequestParam int month, HttpServletResponse response) {
		Agent agent;
		String agentName;
		try {
			agent = agentService.findOne(id);
			agentName = agent.getName();
		} catch (EntityNotFoundException e) {
			return RespMessage.error("代理不存在");
		}
		LocalDate date = LocalDate.of(year, month, 1);
		XSSFWorkbook wb = new XSSFWorkbook();
		MonthlyProfit monthlyProfit = service.findByAgentAndStatistisMonth(agent, date);
		List<ProfitStatistics> list = profitStatisticsService.findByAgentAndMonth(agent, date);
		String fileName = agentName + "-" + year + "年" + month + "月分润统计表";
		buildMonthlyProfit(wb, monthlyProfit, year, month);
		buildProfitStatistics(wb, list, year, month);
		try {
			ExcelUtils.sendExcelToClient(response, wb, fileName);
			return null;
		} catch (IOException e) {
			return RespMessage.error("失败：" + e.getMessage());
		}
	}

	/**
	 * 构建月分润工作簿
	 * 
	 * @param wb
	 *            Excel工作簿
	 * @param monthlyProfit
	 *            月份润详情
	 */
	private void buildMonthlyProfit(XSSFWorkbook wb, MonthlyProfit monthlyProfit, int year, int month) {
		Agent agent = monthlyProfit.getAgent();
		XSSFSheet sheet = wb.createSheet("月分润详情");
		sheet.setDefaultColumnWidth(20);
		String title = agent.getName() + "-" + year + "年" + month + "月分润统计表";
		ExcelUtils.setTitle(sheet, title, 2, 9);
		List<String> head = new ArrayList<>();
		head.add("总分润(元)");
		head.add("微信分润(元)");
		head.add("支付宝分润(元)");
		head.add("总原始分润(元)");
		head.add("微信原始分润(元)");
		head.add("支付宝原始分润(元)");
		head.add("总流水(元)");
		head.add("微信流水(元)");
		head.add("支付宝流水(元)");
		ExcelUtils.setHead(sheet, head, 2, null);
		List<Object> rowData = new ArrayList<>();
		rowData.add(monthlyProfit.getTotalProfit());
		rowData.add(monthlyProfit.getWeixinProfit());
		rowData.add(monthlyProfit.getAlipayProfit());
		rowData.add(monthlyProfit.getTotalOriginalProfit());
		rowData.add(monthlyProfit.getWeixinOriginalProfit());
		rowData.add(monthlyProfit.getAlipayOriginalProfit());
		rowData.add(monthlyProfit.getTotalMoney());
		rowData.add(monthlyProfit.getWeixinMoney());
		rowData.add(monthlyProfit.getAlipayMoney());
		XSSFRow row = sheet.createRow(3);
		ExcelUtils.setRowDatas(row, rowData, null);
		XSSFRow row2 = sheet.createRow(5);
		ExcelUtils.mergedLattice(row2, "服务公司：陕西华贝金服", 5, 6, 0, 1);
		ExcelUtils.mergedLattice(row2, "代理：" + agent.getName(), 5, 6, 3, 4);
		ExcelUtils.mergedLattice(row2, "统计时间：" + year + "年" + month + "月", 5, 6, 6, 7);

		XSSFRow row3 = sheet.createRow(7);
		ExcelUtils.mergedLattice(row3, "微信费率：" + agent.getWeixinRate().toString() + "%", 7, 8, 0, 1);
		ExcelUtils.mergedLattice(row3, "支付宝费率：" + agent.getAlipayRate().toString() + "%", 7, 8, 3, 4);
		ExcelUtils.mergedLattice(row3, "分润比例：" + agent.getProfitProportion() * 100 + "%", 7, 8, 6, 7);

	}

	/**
	 * 构建日分润工作簿
	 * 
	 * @param wb
	 *            Excel工作簿
	 * @param list
	 *            日份润详情
	 */
	private void buildProfitStatistics(XSSFWorkbook wb, List<ProfitStatistics> list, int year, int month) {
		XSSFSheet sheet = wb.createSheet("日分润详情");
		int size = list.size();
		if (size > 0) {
			sheet.setDefaultColumnWidth(20);
			Agent agent = list.get(0).getAgent();
			String title = agent.getName() + "-" + year + "年" + month + "月-日分润统计表详情";
			ExcelUtils.setTitle(sheet, title, 2, 13);
			List<String> head = new ArrayList<>();
			head.add("日期");
			head.add("总分润(元)");
			head.add("微信分润(元)");
			head.add("支付宝分润(元)");
			head.add("总原始分润(元)");
			head.add("微信原始分润(元)");
			head.add("支付宝原始分润(元)");
			head.add("总流水(元)");
			head.add("微信流水(元)");
			head.add("支付宝流水(元)");
			head.add("总订单数");
			head.add("微信订单数");
			head.add("支付宝订单数");
			ExcelUtils.setHead(sheet, head, 2, null);

			// 锁定头部
			sheet.createFreezePane(0, 3, 13, 3);

			List<List<Object>> lists = new ArrayList<>();
			for (ProfitStatistics ps : list) {
				List<Object> data = new ArrayList<>();
				data.add(ps.getStatistisDate().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
				data.add(Double.valueOf(ps.getTotalProfit().toString()));
				data.add(Double.valueOf(ps.getWeixinProfit().toString()));
				data.add(Double.valueOf(ps.getAlipayProfit().toString()));
				data.add(Double.valueOf(ps.getTotalOriginalProfit().toString()));
				data.add(Double.valueOf(ps.getWeixinOriginalProfit().toString()));
				data.add(Double.valueOf(ps.getAlipayOriginalProfit().toString()));
				data.add(Double.valueOf(ps.getTotalMoney().toString()));
				data.add(Double.valueOf(ps.getWeixinMoney().toString()));
				data.add(Double.valueOf(ps.getAlipayMoney().toString()));
				data.add(ps.getTotalCount());
				data.add(ps.getWeixinCount());
				data.add(ps.getAlipayCount());
				lists.add(data);
			}
			ExcelUtils.setDatas(sheet, lists, 3, null);
			int rowNum = sheet.getLastRowNum() +3;
			XSSFRow row = sheet.createRow(rowNum);
			ExcelUtils.mergedLattice(row, "注：当天的交易金额会减去当天的退款金额，所以可能出现交易金额为负数的情况！", rowNum, rowNum+2, 0, 5);
			/*
			 * int rowNum = sheet.getLastRowNum() + 1; XSSFRow row =
			 * sheet.createRow(rowNum); // 合计 使用Excel求和公式 List<String> list1 = new
			 * ArrayList<>(); list1.add("SUM(B4:B" + rowNum + ")"); list1.add("SUM(C4:C" +
			 * rowNum + ")"); list1.add("SUM(D4:D" + rowNum + ")"); list1.add("SUM(E4:E" +
			 * rowNum + ")"); list1.add("SUM(F4:F" + rowNum + ")"); list1.add("SUM(G4:G" +
			 * rowNum + ")"); list1.add("SUM(H4:H" + rowNum + ")"); list1.add("SUM(I4:I" +
			 * rowNum + ")"); list1.add("SUM(J4:J" + rowNum + ")"); list1.add("SUM(K4:K" +
			 * rowNum + ")"); list1.add("SUM(L4:L" + rowNum + ")"); list1.add("SUM(M4:M" +
			 * rowNum + ")"); ExcelUtils.setTotal(row, list1);
			 */
		}

	}
}
